﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BreukADO.Model;

namespace BreukADO
{
    public partial class MaakOpdracht : Form
    {


        ProgrammeerbareBreukContainer breukContainer;
        private BeheerOpdrachten bh;
        DataTable breukenDT, opgavenDT;
        private String[] oplossingen;
        private String[] opgaven;

        public MaakOpdracht(BeheerOpdrachten b)
        {
            InitializeComponent();
            bh = b;
            breukContainer = new ProgrammeerbareBreukContainer();
            // DataTable BREUKEN
            breukenDT = new DataTable();
            breukenDT.Columns.Add("#");
            breukenDT.Columns.Add("Breuk");
            breukenDT.Rows.Add("1", "");
            breukenDT.Rows.Add("2", "");
            dgvBreuken.RowHeadersVisible = false;
            dgvBreuken.DataSource = breukenDT;
            dgvBreuken.Columns[0].Width = 20;
            dgvBreuken.Columns[0].ReadOnly = true;
            // DataTable BREUKEN OPGAVEN
            opgavenDT = new DataTable();
            opgavenDT.Columns.Add("Opgave");
            opgavenDT.Columns.Add("Antwoord");
            dgvOpgaven.RowHeadersVisible = false;
            dgvOpgaven.DataSource = opgavenDT;
            dgvOpgaven.Columns[0].Width = 200;
            dgvOpgaven.Columns[0].ReadOnly = true;
            dgvOpgaven.Columns[1].Width = 60;

            rdbZelfIngeven.Checked = true;
            btnMaakBreuken.Enabled = false;
            txtBovengrens.Enabled = false;
            txtBovengrens.Text = "10";
            txtOndergrens.Enabled = false;
            txtOndergrens.Text = "1";
            rdbBasisBewerkingenGenereren.Checked = true;
            txtAantalOpgaven.Enabled = false;
        }


        private void MaakOpdracht_Load(object sender, EventArgs e)
        {

            this.leerlingTableAdapter.Fill(this.breukADODataSet.Leerling);
            this.opdrachtTableAdapter.Fill(this.breukADODataSet.Opdracht);
            this.opdrachtDetailTableAdapter.Fill(this.breukADODataSet.OpdrachtDetail);
            this.leerlingOpdrachtTableAdapter.Fill(this.breukADODataSet.LeerlingOpdracht);
            this.leerlingOpdrachtDetailTableAdapter.Fill(this.breukADODataSet.LeerlingOpdrachtDetail);
            
           
            VulCmbKlassen();


        }
        private void VulCmbKlassen()
        {

            try
            {
                DataTable dt = leerlingTableAdapter.GetData();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    Boolean found=false;

                    for (int y = 0; y < cmbKlas.Items.Count; y++)
                    {   if(dt.Rows[i]["klas"].ToString()==cmbKlas.Items[y].ToString()){found=true;}           
                    }
                    if (!found) { cmbKlas.Items.Add(dt.Rows[i]["klas"].ToString()); }
                }
                cmbKlas.SelectedIndex = 0;
            }
            catch { }

            cmbKlas.Items.Add("Alle");
        }


        private void cmbKlas_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            String klas = cmbKlas.SelectedItem.ToString();
            if (klas.Equals("Alle"))
            {
                leerlingBindingSource.RemoveFilter();
            }
            else
            {
                leerlingBindingSource.Filter = "Klas = '" + klas + "'";

            }

        }

        private void btnRegistreer_Click(object sender, EventArgs e)
        {
            
            int Moeilijkheidsgraad = Convert.ToInt32(NuDmGraad.Value);
            int MaxScore = Convert.ToInt32(NuDMaxScore.Value);
            DateTime dat = Mc1.SelectionStart;
            List<String> namen= new List<String>();
            
             for(int i=0;i<DGVLeerlingen.SelectedRows.Count;i++){
                 String nm = DGVLeerlingen.SelectedRows[i].Cells[0].Value.ToString();
                 namen.Add(nm);    
            }

        
          

            DataRow thisRow = breukADODataSet.Tables["Opdracht"].NewRow();
            thisRow["opdrachtDatum"] = dat;
            thisRow["moeilijkheidsGraad"] = Moeilijkheidsgraad;
            thisRow["maxScore"] = MaxScore;
            thisRow["status"] = false;
            breukADODataSet.Tables["Opdracht"].Rows.Add(thisRow);
            opdrachtTableAdapter.Update(breukADODataSet.Opdracht);
           

            DataRow thisRow2;
            for (int i = 0; i < opgavenDT.Rows.Count; i++)
            {
                thisRow2 = breukADODataSet.Tables["OpdrachtDetail"].NewRow();
                thisRow2["opgaveTekst"] = opgavenDT.Rows[i]["Opgave"];
                thisRow2["oplossingTekst"] = opgavenDT.Rows[i]["Antwoord"];
                thisRow2["opdrachtID"] = thisRow["opdrachtID"];
                breukADODataSet.Tables["OpdrachtDetail"].Rows.Add(thisRow2);
            }
            opdrachtDetailTableAdapter.Update(breukADODataSet.OpdrachtDetail);


            DataRow thisRow3;
            for (int i = 0; i < namen.Count; i++)
            {
                thisRow3 = breukADODataSet.Tables["LeerlingOpdracht"].NewRow();
                thisRow3["leerlingID"] = DGVLeerlingen.SelectedRows[i].Cells[2].Value.ToString();//SelectedCells[i].Value.ToString();//
                thisRow3["opdrachtID"] = thisRow["opdrachtID"];
                breukADODataSet.Tables["LeerlingOpdracht"].Rows.Add(thisRow3);
            }
            leerlingOpdrachtTableAdapter.Update(breukADODataSet.LeerlingOpdracht);
            
            
            int ant = breukADODataSet.Tables["Opdracht"].Rows.Count;
            MessageBox.Show("gelukt");
            bh.BeheerOpdrachten_Load(null, null);
            
            this.Close();



        }

        private void dgvBreuken_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            try
            {
                dgvBreuken.Rows[e.RowIndex].ErrorText = "";
                if (e.ColumnIndex == 1 && !e.FormattedValue.ToString().Equals(""))
                {
                    String input = e.FormattedValue.ToString();
                    int teller, noemer;
                    if (input.Contains('/'))
                    {
                        String[] inputSplit = input.Split('/');
                        teller = int.Parse(inputSplit[0]);
                        noemer = int.Parse(inputSplit[1]);
                    }
                    else
                    {
                        teller = int.Parse(input);
                        noemer = 1;
                    }
                    breukContainer.AddBreuk(new Breuk(teller, noemer));
                }
            }
            catch (Exception ex)
            {
                e.Cancel = true;
                dgvBreuken.Rows[e.RowIndex].ErrorText = ex.ToString();
                MessageBox.Show("Fout formaat voor breuk!\n\nError: " + ex.ToString(), "Invoer Breuk", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void nupAantalBreuken_ValueChanged(object sender, EventArgs e)
        {
            int aantalBreuken = (int)nupAantalBreuken.Value;
            breukenDT.Rows.Clear();
            for (int i = 0; i < aantalBreuken; i++)
            {
                breukenDT.Rows.Add(i + 1, "");
            }
        }

        private void rdbZelfIngeven_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbZelfIngeven.Checked)
            {
                btnMaakBreuken.Enabled = false;
                breukContainer = new ProgrammeerbareBreukContainer();
                dgvBreuken.Enabled = true; breukenDT.Rows.Clear();
                for (int i = 0; i < (int)nupAantalBreuken.Value; i++)
                {
                    breukenDT.Rows.Add(i + 1, "");
                }
            }
            else
            {
                dgvBreuken.Enabled = false;
            }
        }

        private void rdbGenererenZonderBeperkingen_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbGenererenZonderBeperkingen.Checked)
            {
                btnMaakBreuken.Enabled = true;
                breukContainer = new ProgrammeerbareBreukContainer();
                dgvBreuken.Enabled = true; breukenDT.Rows.Clear();
                for (int i = 0; i < (int)nupAantalBreuken.Value; i++)
                {
                    breukenDT.Rows.Add(i + 1, "");
                }
            }
            else
            {
                btnMaakBreuken.Enabled = false;
            }
        }

        private void rdbGenererenMetBeperkingen_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbGenererenMetBeperkingen.Checked)
            {
                btnMaakBreuken.Enabled = true;
                txtOndergrens.Enabled = true;
                txtBovengrens.Enabled = true;
                breukContainer = new ProgrammeerbareBreukContainer();
                dgvBreuken.Enabled = true; breukenDT.Rows.Clear();
                for (int i = 0; i < (int)nupAantalBreuken.Value; i++)
                {
                    breukenDT.Rows.Add(i + 1, "");
                }
            }
            else
            {
                btnMaakBreuken.Enabled = false;
                txtOndergrens.Enabled = false;
                txtBovengrens.Enabled = false;
            }
        }

        private void rdbRandomBewerkingenGenereren_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbRandomBewerkingenGenereren.Checked) 
            { 
                txtAantalOpgaven.Enabled = true;
            } 
            else 
            { 
                txtAantalOpgaven.Enabled = false; 
            }
        }

        private void btnMaakBreuken_Click(object sender, EventArgs e)
        {
            breukContainer = new ProgrammeerbareBreukContainer();
            if (rdbGenererenMetBeperkingen.Checked)
            {
                int onderGrens, bovenGrens;
                if (int.TryParse(txtOndergrens.Text, out onderGrens) && int.TryParse(txtBovengrens.Text, out bovenGrens))
                {
                    if (bovenGrens > onderGrens)
                    {
                        breukenDT.Rows.Clear();
                        breukContainer = new ProgrammeerbareBreukContainer();
                        for (int i = 0; i < (int)nupAantalBreuken.Value; i++)
                        {
                            Breuk breuk = Breuk.RandomBreuk(onderGrens, bovenGrens);
                            breuk.Vereenvoudig();
                            breukContainer.AddBreuk(breuk);
                            breukenDT.Rows.Add(i + 1, breuk.Toon());
                        }
                    }
                    else
                    {
                        MessageBox.Show("De bovengrens moet groter zijn dan de ondergrens!", "Ongeldige invoer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                }
                else
                {
                    MessageBox.Show("Geef geldige onder- en bovengrens!", "Ongeldige invoer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
            else
            {
                breukenDT.Rows.Clear();
                for (int i = 0; i < (int)nupAantalBreuken.Value; i++)
                {
                    Breuk breuk = Breuk.RandomBreuk(-9999, 9999); // toch een limiet ingesteld om leesbaar te houden !!!
                    breuk.Vereenvoudig();
                    breukContainer.AddBreuk(breuk);
                    breukenDT.Rows.Add(i + 1, breuk.Toon());
                }
            }
        }

        private void btnOpgavenGenereren_Click(object sender, EventArgs e)
        {
            dgvOpgaven.Columns[0].ReadOnly = true;
            if (rdbBasisBewerkingenGenereren.Checked) maakOpgavenBasisberwerkingen();
            else maakOpgavenRandombewerkingen();
        }

        private void maakOpgavenBasisberwerkingen()
        {
            opgavenDT.Rows.Clear();
            int aantalBreuken = breukContainer.AantalBreuken();
            String outOpt = "", outAft = "", outVer = "", outDel = "";
            String[] sOpt = new String[aantalBreuken - 1], sAft = new String[aantalBreuken - 1], sVer = new String[aantalBreuken - 1], sDel = new String[aantalBreuken - 1];
            DelegateBreukenBewerking[] dOpt = new DelegateBreukenBewerking[aantalBreuken], dAft = new DelegateBreukenBewerking[aantalBreuken], dVer = new DelegateBreukenBewerking[aantalBreuken], dDel = new DelegateBreukenBewerking[aantalBreuken];
            for (int i = 0; i < aantalBreuken; i++)
            {
                outOpt += dgvBreuken.Rows[i].Cells[1].Value.ToString();
                outAft += dgvBreuken.Rows[i].Cells[1].Value.ToString();
                outVer += dgvBreuken.Rows[i].Cells[1].Value.ToString();
                outDel += dgvBreuken.Rows[i].Cells[1].Value.ToString();
                if (i < aantalBreuken - 1)
                {
                    dOpt[i] = new DelegateBreukenBewerking(Breuk.TelOp);
                    dAft[i] = new DelegateBreukenBewerking(Breuk.TrekAf);
                    dVer[i] = new DelegateBreukenBewerking(Breuk.Vermenigvuldig);
                    dDel[i] = new DelegateBreukenBewerking(Breuk.Delen);
                    sOpt[i] = "+";
                    sAft[i] = "-";
                    sVer[i] = "*";
                    sDel[i] = "/";
                    outOpt += " + ";
                    outAft += " - ";
                    outVer += " * ";
                    outDel += " : ";
                }
            }
            Breuk[] uitkomstOpt = breukContainer.DoeBewerking(dOpt, sOpt);
            opgavenDT.Rows.Add(outOpt, ((Breuk)uitkomstOpt[0]).Toon());
            Breuk[] uitkomstAft = breukContainer.DoeBewerking(dAft, sAft);
            opgavenDT.Rows.Add(outAft, ((Breuk)uitkomstAft[0]).Toon());
            Breuk[] uitkomstVer = breukContainer.DoeBewerking(dVer, sVer);
            opgavenDT.Rows.Add(outVer, ((Breuk)uitkomstVer[0]).Toon());
            Breuk[] uitkomstDel = breukContainer.DoeBewerking(dDel, sDel);
            opgavenDT.Rows.Add(outDel, ((Breuk)uitkomstDel[0]).Toon());
        }

        private void maakOpgavenRandombewerkingen()
        {
            try
            {
                opgavenDT.Rows.Clear();
                int aantalBreuken = breukContainer.AantalBreuken();
                int aantalOpgaven = Int32.Parse(txtAantalOpgaven.Text);
                opgaven = new String[aantalOpgaven];
                oplossingen = new String[aantalOpgaven];
                String[] operandenRandom = { "+", "-", "*", "/" };
                Random randomGenerator = new Random();
                for (int i = 0; i < opgaven.Length; i++)
                {
                    String[] operanden = new String[breukContainer.AantalBreuken()];
                    DelegateBreukenBewerking[] delegates = new DelegateBreukenBewerking[breukContainer.AantalBreuken()];
                    for (int j = 0; j < breukContainer.Breuken.Count; j++)
                    {
                        if (j == breukContainer.Breuken.Count - 1)
                        {
                            opgaven[i] += breukContainer.Breuken[j].ToString();
                        }
                        else
                        {
                            int boe = randomGenerator.Next(0, 3);
                            operanden[j] = operandenRandom[boe];
                            opgaven[i] += breukContainer.Breuken[j].ToString() + " " + operanden[j] + " ";
                            switch (operanden[j])
                            {
                                case "+": delegates[j] = new DelegateBreukenBewerking(Breuk.TelOp); break;
                                case "-": delegates[j] = new DelegateBreukenBewerking(Breuk.TrekAf); break;
                                case "*": delegates[j] = new DelegateBreukenBewerking(Breuk.Vermenigvuldig); break;
                                case "/": delegates[j] = new DelegateBreukenBewerking(Breuk.Delen); break;
                            }
                        }
                    }
                    oplossingen[i] = breukContainer.TestIets(delegates, operanden).ToString();
                    opgavenDT.Rows.Add(opgaven[i], oplossingen[i]);
                }


            }
            catch (FormatException e)
            {
                MessageBox.Show("Geen geldige invoer!\n\nError: " + e.Message, "Invoer Aantal Opgaven", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

    }
}
